﻿// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

#region

using Furion.DataEncryption;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.JsonWebTokens;

#endregion

namespace Neto.Web;

/// <summary>
///     Web帮助类
/// </summary>
public static class WebHelper
{
    /// <summary>
    ///     传入参数验证(表示验证请求结果的容器。)
    /// </summary>
    /// <param name="errorMessage">错误消息</param>
    /// <param name="memberNames">成员名称，例如： nameof(due_payment)</param>
    /// <param name="isLocalization">是否全球化，默认true</param>
    /// <returns></returns>
    public static ValidationResult Validation(string errorMessage, IEnumerable<string>? memberNames = null,
        bool isLocalization = true)
    {
        return isLocalization
            ? new ValidationResult(L.Text[errorMessage], memberNames)
            : new ValidationResult(errorMessage, memberNames);
    }

    #region JWT

    /// <summary>
    ///     JWTtoken手动刷新
    /// </summary>
    /// <param name="httpContext"></param>
    public static void ManualRefreshJwtToken(HttpContext httpContext)
    {
        var expiredToken = GetJwtBearerToken();
        var refreshToken = GetJwtBearerToken("X-Authorization");
        if (string.IsNullOrWhiteSpace(expiredToken) || string.IsNullOrWhiteSpace(refreshToken)) return;

        // 交换新的 Token
        var accessToken = JWTEncryption.Exchange(expiredToken, refreshToken);
        if (string.IsNullOrWhiteSpace(accessToken)) return;
        // 读取新的 Token Clamis
        var claims = JWTEncryption.ReadJwtToken(accessToken)?.Claims;
        if (claims == null) return;

        // 创建身份信息
        var claimIdentity = new ClaimsIdentity("AuthenticationTypes.Federation");
        claimIdentity.AddClaims(claims);
        var claimsPrincipal = new ClaimsPrincipal(claimIdentity);

        // 设置 HttpContext.User 并登录
        httpContext.User = claimsPrincipal;
        httpContext.SignInAsync(claimsPrincipal);

        string accessTokenKey = "access-token",
            xAccessTokenKey = "x-access-token",
            accessControlExposeKey = "Access-Control-Expose-Headers";

        // 返回新的 Token
        httpContext.Response.Headers[accessTokenKey] = accessToken;
        // 返回新的 刷新Token
        httpContext.Response.Headers[xAccessTokenKey] = JWTEncryption.GenerateRefreshToken(accessToken);

        // 处理 axios 问题
        httpContext.Response.Headers.TryGetValue(accessControlExposeKey, out var acehs);
        httpContext.Response.Headers[accessControlExposeKey] = string.Join(',',
            StringValues.Concat(acehs, new StringValues(new[] { accessTokenKey, xAccessTokenKey })).Distinct());
    }

    /// <summary>
    ///     JWTtoken手动刷新
    /// </summary>
    public static void ManualRefreshJwtToken()
    {
        ManualRefreshJwtToken(App.HttpContext);
    }

    /// <summary>
    ///     获取 JWT Bearer Token
    /// </summary>
    /// <param name="headerKey"></param>
    /// <param name="tokenPrefix"></param>
    /// <returns></returns>
    public static string? GetJwtBearerToken(string headerKey = "Authorization", string tokenPrefix = "Bearer ")
    {
        // 判断请求报文头中是否有 "Authorization" 报文头
        var bearerToken = App.HttpContext.Request.Headers[headerKey].ToString();
        if (string.IsNullOrWhiteSpace(bearerToken)) return default;

        var prefixLenght = tokenPrefix.Length;
        return bearerToken.StartsWith(tokenPrefix, true, null) && bearerToken.Length > prefixLenght
            ? bearerToken[prefixLenght..].Trim()
            : default;
    }

    /// <summary>
    ///     获取JWT登录信息
    /// </summary>
    /// <returns></returns>
    public static JsonWebToken? GetJwtJsonWebToken()
    {
        // 获取请求头中的JWT
        var accessToken = GetJwtBearerToken();
        if (string.IsNullOrEmpty(accessToken)) return null;
        var (isValid, jsonWebToken, validationResult) = JWTEncryption.Validate(accessToken);
        //JWT验证成功
        return isValid ? jsonWebToken : null;
    }

    /// <summary>
    ///     获取JWT登录信息 Claim
    /// </summary>
    /// <returns></returns>
    public static IEnumerable<Claim> GetJwtLoginInfo()
    {
        // 获取请求头中的JWT
        var accessToken = GetJwtBearerToken();
        if (string.IsNullOrEmpty(accessToken)) return [];
        var (isValid, jsonWebToken, validationResult) = JWTEncryption.Validate(accessToken);
        return isValid ? jsonWebToken.Claims : [];
    }
    //
    // /// <summary>
    // /// 获取JWT UserId
    // /// </summary>
    // /// <returns></returns>
    // public static long GetJwtUserId()
    // {
    //     return GetJwtClaim("UserId")?.ToLong() ?? 0;
    // }
    //
    // /// <summary>
    // /// 获取JWT Claim
    // /// </summary>
    // /// <param name="claimType"></param>
    // /// <returns></returns>
    // public static string? GetJwtClaim(string claimType)
    // {
    //     var claims = GetJwtLoginInfo();
    //     var userClaim = claims.FirstOrDefault(c => c.Type == claimType);
    //     return userClaim?.Value;
    // }

    #endregion
}